﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using Negocio = PSE.Tools.CadastroMensagens.Negocio;
using NegocioProdutos = PSE.Tools.CadastroProdutos.Negocio;
using Entidades = PSE.Tools.CadastroMensagens.Entidades;
using EntidadesProduto = PSE.Tools.CadastroProdutos.Entidades;
using PSE.Tools.Util.Entidades;
using System;
using System.Linq;
using System.Text;

namespace CadastroMensagensTest
{
    [TestClass()]
    public class ProdutosTest
    {
        #region [ Inserir ]
        [TestMethod]
        public void InsereProdutoComEntidadeNula()
        {
            bool ok = false;
            NegocioProdutos.Produtos negocio = new NegocioProdutos.Produtos();
            try
            {
                negocio.Inserir(null);
            }
            catch (System.ArgumentNullException)
            {
                ok = true;
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void InsereProdutoComNomeComMaisDe30Caracteres()
        {
            bool ok = false;
            NegocioProdutos.Produtos negocio = new NegocioProdutos.Produtos();
            try
            {
                Entidades.Produto Produto = new Entidades.Produto();
                Produto.Nome = StringUtil.RetornaTextoAleatorio(35);
                negocio.Inserir(Produto);
            }
            catch (ValidacaoEntidadeException ex)
            {
                ok = ex.Validacoes.First().NomePropriedade.Equals("Nome", System.StringComparison.CurrentCultureIgnoreCase);
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void InsereProdutoComNomeVazio()
        {
            bool ok = false;
            Negocio.Produtos negocio = new Negocio.Produtos();
            try
            {
                Entidades.Produto Produto = new Entidades.Produto();
                Produto.Nome = "";
                negocio.Inserir(Produto);
            }
            catch (ValidacaoEntidadeException ex)
            {
                ok = ex.Validacoes.First().NomePropriedade.Equals("Nome", System.StringComparison.CurrentCultureIgnoreCase);
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void InsereProdutoComNomeJaCadastrado()
        {
            bool ok = false;
            Negocio.Produtos negocio = new Negocio.Produtos();
            var entidadeJaExistente = negocio.Selecionar()[0];
            Entidades.Produto entidadeNova = new Entidades.Produto { Nome = entidadeJaExistente.Nome};
            try
            {
                negocio.Inserir(entidadeNova);
            }
            catch (ValidacaoEntidadeException ex)
            {
                ok = ex.Validacoes.First().NomePropriedade.Equals("Nome");
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void InsereProdutoComSucesso()
        {
            bool ok = true;
            Negocio.Produtos negocio = new Negocio.Produtos();
            Entidades.Produto entidadeNova = new Entidades.Produto { Nome = StringUtil.RetornaTextoAleatorio(30) };
            try
            {
                negocio.Inserir(entidadeNova);
            }
            catch (Exception)
            {
                ok = false;
            }
            Assert.IsTrue(ok);
        }
        #endregion [ Inserir ]

        #region [ Atualizar ]
        [TestMethod]
        public void AtualizaProdutoComEntidadeNula()
        {
            bool ok = false;
            Negocio.Produtos negocio = new Negocio.Produtos();
            try
            {
                negocio.Atualizar(null);
            }
            catch (System.ArgumentNullException)
            {
                ok = true;
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void AtualizaProdutoComNomeVazio()
        {
            bool ok = false;
            Negocio.Produtos negocio = new Negocio.Produtos();
            try
            {
                Entidades.Produto Produto = negocio.Selecionar()[0];
                Produto.Nome = "";
                negocio.Atualizar(Produto);
            }
            catch (ValidacaoEntidadeException ex)
            {
                ok = ex.Validacoes.First().NomePropriedade.Equals("Nome", System.StringComparison.CurrentCultureIgnoreCase);
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void AtualizaProdutoComNomeComMaisDe30Caracteres()
        {
            bool ok = false;
            Negocio.Produtos negocio = new Negocio.Produtos();
            try
            {
                Entidades.Produto Produto = negocio.Selecionar()[0];
                Produto.Nome = StringUtil.RetornaTextoAleatorio(35);
                negocio.Atualizar(Produto);
            }
            catch (ValidacaoEntidadeException ex)
            {
                ok = ex.Validacoes.First().NomePropriedade.Equals("Nome", System.StringComparison.CurrentCultureIgnoreCase);
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void AtualizaProdutoComNomeJaCadastrado()
        {
            bool ok = true;
            Negocio.Produtos negocio = new Negocio.Produtos();
            Entidades.Produto Produto1 = negocio.Selecionar()[0];
            Entidades.Produto Produto2 = negocio.Selecionar()[1];
            Produto2.Nome = Produto1.Nome;
            try
            {
                negocio.Atualizar(Produto2);
            }
            catch (ValidacaoEntidadeException ex)
            {
                ok = ex.Validacoes.First().NomePropriedade.Equals("Nome");
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void AtualizaProdutoComSucesso()
        {
            bool ok = true;
            Negocio.Produtos negocio = new Negocio.Produtos();
            Entidades.Produto Produto1 = negocio.Selecionar()[0];
            try
            {
                negocio.Atualizar(Produto1);
            }
            catch (Exception)
            {
                ok = false;
            }
            Assert.IsTrue(ok);
        }
        #endregion [ Atualizar ]

        #region [ Excluir ]
        [TestMethod]
        public void ExcluirProdutoNulo()
        {
            bool ok = false;
            Negocio.Produtos negocio = new Negocio.Produtos();
            try
            {
                negocio.Excluir(null);
            }
            catch (ArgumentNullException)
            {
                ok = true;
            }
            catch (Exception)
            {
                ok = false;
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void ExcluirProdutoComSucesso()
        {
            bool ok = false;
            Negocio.Produtos negocio = new Negocio.Produtos();
            int id = negocio.Selecionar().Count + 1;
            Entidades.Produto entidadeNova = new Entidades.Produto { Id = id, Nome = StringUtil.RetornaTextoAleatorio(30) };
            try
            {
                negocio.Inserir(entidadeNova);
                var entidade = negocio.ObterPorId(id);
                negocio.Excluir(entidade);
                entidade = negocio.ObterPorId(id);
                ok = (entidade == null);
            }
            catch (Exception)
            {
                ok = false;
            }
            Assert.IsTrue(ok);
        }
        #endregion [ Excluir ]

        #region [ Obter ]
        [TestMethod]
        public void ObterProdutoComIdVazio()
        {
            bool ok = false;
            Negocio.Produtos negocio = new Negocio.Produtos();
            try
            {
                var Produto = negocio.ObterPorId(0);
            }
            catch (ArgumentException)
            {
                ok = true;
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void ObterProdutoComSucesso()
        {
            bool ok = true;
            Negocio.Produtos negocio = new Negocio.Produtos();
            int id = negocio.Selecionar().Count + 1;
            Entidades.Produto entidadeNova = new Entidades.Produto { Id = id, Nome = StringUtil.RetornaTextoAleatorio(30) };
            try
            {
                negocio.Inserir(entidadeNova);
                var entidade = negocio.ObterPorId(id);
                ok = (entidade != null);
            }
            catch (Exception)
            {
                ok = false;
            }
            Assert.IsTrue(ok);
        }
        #endregion [ Obter ]

        #region [ Selecionar ]
        [TestMethod]
        public void SelecionarProdutosComSucesso()
        {
            bool ok = true;
            Negocio.Produtos negocio = new Negocio.Produtos();
            int id = negocio.Selecionar().Count + 1;
            Entidades.Produto entidadeNova = new Entidades.Produto { Id = id, Nome = StringUtil.RetornaTextoAleatorio(30) };
            try
            {
                negocio.Inserir(entidadeNova);
                var entidade = negocio.ObterPorId(id);
                ok = negocio.Selecionar().Count > 0;
            }
            catch (Exception)
            {
                ok = false;
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void SelecionarProdutosComFiltroInvalido()
        {
            bool ok = false;
            Negocio.Produtos negocio = new Negocio.Produtos();
            try
            {
                var entidades = negocio.Selecionar(null);
            }
            catch (ArgumentNullException)
            {
                ok = true;
            }
            Assert.IsTrue(ok);
        }

        [TestMethod]
        public void SelecionarProdutosComFiltroPeloNome()
        {
            bool ok = true;
            Negocio.Produtos negocio = new Negocio.Produtos();
            int id = negocio.Selecionar().Count + 1;
            string nome = StringUtil.RetornaTextoAleatorio(30);
            Entidades.Produto entidadeNova = new Entidades.Produto { Id = id, Nome = nome };
            try
            {
                negocio.Inserir(entidadeNova);
                var entidades = negocio.Selecionar(i => i.Nome.Equals(nome));
                ok = entidades.Count == 1;
            }
            catch (Exception)
            {
                ok = false;
            }
            Assert.IsTrue(ok);
        }
        #endregion [ Selecionar ]
    }
}
